﻿Module Utils
    ' Retourne l'angle entre deux stations
    Function GetAngle(ByRef S1 As Station, ByRef S2 As Station) As Double
        Return Math.Atan2(S2.Y - S1.Y, S2.X - S1.X)
    End Function

    ' Retourne la distance entre deux stations
    Function GetDistance(ByRef S1 As Station, ByRef S2 As Station) As Double
        Return Math.Sqrt(Math.Pow(S1.X - S2.X, 2) + Math.Pow(S1.Y - S2.Y, 2))
    End Function

    ' Recherche l'identifiant de la jonction dans la liste en fonction de ses stations de départ et d'arrivée
    Function GetJunctionID(ByVal S1 As Integer, ByVal S2 As Integer, ByRef Junctions As List(Of Junction)) As Integer
        ' Pour chaque jonction existante
        For Each Junction As Junction In Junctions
            ' On teste si la station est la suite de la station en cours
            If ((Junction.FromStation = S1) And (Junction.ToStation = S2)) Or _
               ((Junction.ToStation = S1) And (Junction.FromStation = S2)) Then
                Return Junctions.IndexOf(Junction)
            End If
        Next

        ' Si aucune ne correspond, on renvoie -1
        Return -1
    End Function

    ' Retourne la liste des stations directement reliées à une station dont l'index est donné
    Function GetNeighbors(StationIndex As Integer, ByRef Junctions As List(Of Junction), _
                          ByRef RailPoints As List(Of RailPoint), Optional Exclude As Integer = -1) As List(Of Integer)
        ' On créé une liste représentant toutes les jonctions possibles
        Dim PossibleJunctions As New List(Of Integer)

        ' Pour chaque jonction
        For Each Junction In Junctions
            ' On teste si la station est la suite de la station en cours
            If (Junction.FromStation = StationIndex) And (Junction.ToStation <> Exclude) Then
                PossibleJunctions.Add(Junctions.IndexOf(Junction))
            ElseIf (Junction.ToStation = StationIndex) And (Junction.FromStation <> Exclude) Then
                PossibleJunctions.Add(Junctions.IndexOf(Junction))
            End If
        Next

        Dim SID As Integer

        ' Pour chaque aiguillage
        For Each RailPoint In RailPoints
            SID = GetJunctionID(If(RailPoint.ActiveJunction, RailPoint.EndStation1Index, RailPoint.EndStation2Index), RailPoint.MiddleStationIndex, Junctions)
            ' Si la jonction active est sélectionnée, on la supprime
            If PossibleJunctions.Contains(SID) Then PossibleJunctions.Remove(SID)
        Next

        Dim Result As New List(Of Integer)

        ' Puis on renvoie uniquement la station située à l'extrémité des jonctions sélectionnées
        For Each Junction In PossibleJunctions
            If Junctions.Item(Junction).FromStation = StationIndex Then
                Result.Add(Junctions.Item(Junction).ToStation)
            ElseIf Junctions.Item(Junction).ToStation = StationIndex Then
                Result.Add(Junctions.Item(Junction).FromStation)
            End If
        Next

        ' Et on renvoie la liste des stations possibles
        Return Result
    End Function
End Module
